from io import StringIO
class Stanza(dict):
    def Copy(s):
        result=Stanza()
        for i in s.keys():
            result[i]=s[i]
        return result
    def WriteTo(s,strBuff,isSource,isRelease, isInstaller):
        canonicalOrder = canonicalOrderBinary
        if isSource :
            canonicalOrder = canonicalOrderSource
        
        if isRelease :
            canonicalOrder = canonicalOrderRelease
        
        if isInstaller :
            canonicalOrder = canonicalOrderInstaller
        for field in canonicalOrder:
            value=s.get(field)
            if field in s:
                s.pop(field)
                writeField(strBuff,field,value,isRelease)
        # no extra fields in installer
        if not isInstaller :
            # Print extra fields in deterministic order (alphabetical)
            keys =[]
            
            for field in s.keys():
                keys.append(field)
            keys.sort()
            for field in keys:
                writeField(strBuff,field,s[field],isRelease)
        return None


MaxFieldSize = 2 * 1024 * 1024
canonicalOrderRelease = ["Origin",
        "Label",
        "Archive",
        "Suite",
        "Version",
        "Codename",
        "Date",
        "NotAutomatic",
        "ButAutomaticUpgrades",
        "Architectures",
        "Architecture",
        "Components",
        "Component",
        "Description",
        "MD5Sum",
        "SHA1",
        "SHA256",
        "SHA512",]

canonicalOrderBinary = ["Package",
    "Essential",
    "Status",
    "Priority",
    "Section",
    "Installed-Size",
    "Maintainer",
    "Original-Maintainer",
    "Architecture",
    "Source",
    "Version",
    "Replaces",
    "Provides",
    "Depends",
    "Pre-Depends",
    "Recommends",
    "Suggests",
    "Conflicts",
    "Breaks",
    "Conffiles",
    "Filename",
    "Size",
    "MD5Sum",
    "MD5sum",
    "SHA1",
    "SHA256",
    "SHA512",
    "Description",]

canonicalOrderSource = ["Package",
    "Source",
    "Binary",
    "Version",
    "Priority",
    "Section",
    "Maintainer",
    "Original-Maintainer",
    "Build-Depends",
    "Build-Depends-Indep",
    "Build-Conflicts",
    "Build-Conflicts-Indep",
    "Architecture",
    "Standards-Version",
    "Format",
    "Directory",
    "Files",]

canonicalOrderInstaller = ["",]

def isMultilineField(field,isRelease):
    dic={'':True,'Description':True,
    'Files':True,
    'Changes':True,'Checksums-Sha1':True,'Checksums-Sha256':True,'Checksums-Sha512':True,'Package-List':True,
    'MD5Sum':isRelease,'SHA1':isRelease,'SHA256':isRelease,'SHA512':isRelease}
    if field in dic:
        return dic[field]
    return False
# strBuff是StringIO
def writeField(strBuff,field,value,isRelease):
    if not isMultilineField(field, isRelease):
        strBuff.write('{}: {}\n'.format(field,value))
    else:
        if field!='' and not value.endswith('\n'):
            value=value+'\n'
        if field !='Description' and field !='':
            value='\n'+value
        if field!='':
            strBuff.write('{}:{}'.format(field,value))
        else:
            strBuff.write(value)
    return

#Parsing errors

#    ErrMalformedStanza = errors.New("malformed stanza syntax")


def canonicalCase(field ):
    upper= field.upper()
    upperDic={
        "SHA1":upper, "SHA256":upper, "SHA512":upper,"MD5SUM":'MD5Sum',"NOTAUTOMATIC":'NotAutomatic',"BUTAUTOMATICUPGRADES":'ButAutomaticUpgrades'
    }
    if upperDic.get(upper) is not None:
        return upperDic.get(upper)

    startOfWord = True
    fieldStrList=list(field)
    for i in range(len(fieldStrList)):

        if startOfWord:
            startOfWord=False
            fieldStrList[i]=fieldStrList[i].upper()
            continue
        if fieldStrList[i]=='-':
            startOfWord=True
        fieldStrList[i]=fieldStrList[i].lower()
    return ''.join(fieldStrList)




class ControlFileReader:
    scanner=None
    isRelease=None   
    isInstaller =None
    def __init__(self) -> None:
        self.scanner=StringIO()
    # // ReadStanza reeads one stanza from control file
    def  ReadStanza(self)  :
        stanza = Stanza()
        lastField = ""
        lastFieldMultiline = self.isInstaller
        for line in self.scanner.readlines():
            line=line.rstrip()
            if line=='':
                if len(stanza)>0:
                    return stanza,None
                continue


            if line[0] == ' ' or line[0] == '\t' or self.isInstaller :
                if lastFieldMultiline :
                    stanza[lastField] += line + "\n"
                else :
                    stanza[lastField] += " " + line.strip()
                
            else :
                parts = line.split( ":", 1)
                if len(parts) != 2 :
                    
                    return None,'malformed stanza syntax'
                
                lastField = canonicalCase(parts[0])
                lastFieldMultiline = isMultilineField(lastField, self.isRelease)
                if lastFieldMultiline :
                    stanza[lastField] = parts[1]
                    if parts[1] != "" :
                        stanza[lastField] += "\n"
                    
                else :
                    stanza[lastField] = parts[1].strip()
        if len(stanza) > 0 :
            return stanza,None
        return None,None
        

# // NewControlFileReader creates ControlFileReader, it wraps with buffering
def NewControlFileReader(r, isRelease, isInstaller ) :
    readData=r.read(32768)
    if isinstance(readData,bytes):
        readData=readData.decode()
    scnr =StringIO(readData)
    # 功能未知，暂不翻译
    # scnr.Buffer(None, MaxFieldSize)

    controlfilereader=ControlFileReader()
    controlfilereader.scanner=scnr
    controlfilereader.isRelease=isRelease
    controlfilereader.isInstaller=isInstaller
    return controlfilereader


